package com.ruoyi.smartai.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONReader;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.smartai.domain.FansContent;
import com.ruoyi.smartai.domain.FansUtil;
import com.ruoyi.smartai.service.IDialogIntentService;
import com.ruoyi.smartai.service.IFansUtilService;
import com.ruoyi.smartai.utils.WhatsAPPUtils;
import com.ruoyi.system.domain.ChatLog;
import com.ruoyi.system.domain.CustomerInfo;
import com.ruoyi.system.domain.FansInfo;
import com.ruoyi.system.mapper.ChatLogMapper;
import com.ruoyi.system.mapper.CustomerInfoMapper;
import com.ruoyi.system.mapper.FansInfoMapper;
import com.ruoyi.system.mapper.StandardScriptMapper;
import com.ruoyi.system.service.IFansInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class FansUtilServiceImpl implements IFansUtilService {
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IDialogIntentService dialogIntentService;

    @Autowired
    private FansInfoMapper fansInfoMapper;

    @Autowired(required = false)
    private CustomerInfoMapper customerInfoMapper;

    @Autowired(required = false)
    private ChatLogMapper chatLogMapper;

    @Override
    public FansUtil getFansUtil() {
        String key = "persona:customer:";
        FansUtil fansUtil = new FansUtil();
        String apikey = redisCache.getCacheObject(key + "apikey");
        String modelsName = redisCache.getCacheObject(key + "modelsname");
        String fansIntent = redisCache.getCacheObject(key + "fansintent");
        fansUtil.setApikey(apikey);
        fansUtil.setFansintent(fansIntent);
        fansUtil.setModelsname(modelsName);
        return fansUtil;
    }

    @Override
    public int updateFansUtil(FansUtil fansUtil) {
        if (StringUtils.isNotNull(fansUtil.getApikey())) {
            redisCache.setCacheObject("persona:customer:apikey", fansUtil.getApikey());
        }
        if (StringUtils.isNotNull(fansUtil.getModelsname())) {
            redisCache.setCacheObject("persona:customer:modelsname", fansUtil.getModelsname());
        }
        if (StringUtils.isNotNull(fansUtil.getFansintent())) {
            redisCache.setCacheObject("persona:customer:fansintent", fansUtil.getFansintent());
        }
        return 0;
    }

    @Override
    public FansContent fanAnalysis(String fansNumber, String customerNumber) {
        String dialogs = formatPrompt(fansNumber, customerNumber, 100);
        String intentPrompt = redisCache.getCacheObject("persona:customer:fansintent");
        intentPrompt = intentPrompt.replace("{dialog}", dialogs);
        String jsonInput = WhatsAPPUtils.getChatIntent(intentPrompt,fansNumber);
        FansContent fansContent = parseFansContent(jsonInput);
        if (fansContent != null) {
            FansInfo fansInfo = fansInfoMapper.selectChatByClientNumber(fansNumber);
            LocalDateTime localDateTime = LocalDateTime.ofInstant(fansInfo.getCreateTime().toInstant(), ZoneId.systemDefault());
            DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            fansContent.setStartTime(localDateTime.format(formatter1));
        }
        return fansContent;
    }

    // 清理非JSON内容
    public FansContent parseFansContent(String input) {
        try {
            // 检查输入是否已经是一个JSON格式
            if (input.trim().startsWith("{") && input.trim().endsWith("}")) {
                // 输入已经是JSON格式，直接解析
                return parseJsonString(input);
            } else {
                // 使用正则表达式提取 JSON 部分（用于从Markdown中提取）
                Pattern pattern = Pattern.compile("```(?:json)?\\s*(\\{.*?\\})\\s*```", Pattern.DOTALL);
                Matcher looseMatcher = pattern.matcher(input);

                if (looseMatcher.find()) {
                    String jsonStr = looseMatcher.group(1).trim();
                    return parseJsonString(jsonStr);
                } else {
                    // 尝试查找不带markdown格式的JSON对象
                    Pattern jsonPattern = Pattern.compile("\\{[\\s\\S]*?\\}", Pattern.DOTALL);
                    Matcher jsonMatcher = jsonPattern.matcher(input);

                    if (jsonMatcher.find()) {
                        String jsonStr = jsonMatcher.group(0);
                        return parseJsonString(jsonStr);
                    } else {
                        throw new RuntimeException("无法从输入中提取 JSON 数据");
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("解析 JSON 时发生错误：" + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    // 提取解析JSON字符串为FansContent的方法
    private FansContent parseJsonString(String jsonStr) throws IOException {
        // 清理JSON字符串中的转义字符，但不要过度清理
        // 只替换字符串字面量中的 \n 和 \r
//        String cleanedStr = jsonStr.replace("\\n", "").replace("\\r", "");
        String cleanedStr = jsonStr.replace("\\n", "");
        cleanedStr = cleanedStr.replace(" ", "");
        cleanedStr = cleanedStr.replace("\\s", "");
        cleanedStr = cleanedStr.replace("\\", "");
        cleanedStr = cleanedStr.replace("[", "");
        cleanedStr = cleanedStr.replace("]", "");

        // 使用Jackson直接解析为FansContent对象
        ObjectMapper mapper = new ObjectMapper();
        // 设置反序列化特性以提高容错性
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 添加允许JSON中包含注释的配置
        mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);

        try {
            // 直接解析为FansContent对象
            return mapper.readValue(cleanedStr, FansContent.class);
        } catch (Exception e) {
            // 如果直接解析失败，先解析为Map，再转换
            Map<String, Object> dataMap = mapper.readValue(cleanedStr,
                    new TypeReference<Map<String, Object>>() {
                    });

            FansContent fansContent = new FansContent();
            fansContent.setName((String) dataMap.get("name"));
            fansContent.setCountry((String) dataMap.get("country"));

            // 处理age，可能是整数或字符串
            Object ageObj = dataMap.get("age");
            if (ageObj != null) {
                if (ageObj instanceof Integer) {
                    fansContent.setAge((Integer) ageObj);
                } else if (ageObj instanceof String) {
                    try {
                        fansContent.setAge(Integer.parseInt((String) ageObj));
                    } catch (NumberFormatException nfe) {
                        // 无法解析为数字时保持默认值
                    }
                }
            }

            fansContent.setOccupation((String) dataMap.get("occupation"));
            fansContent.setInterests((String) dataMap.get("interests"));

            // 处理可能有两个不同名称的性格分析字段
            String characterAnalysis = (String) dataMap.get("characterAnalysis");
            String personalityAnalysis = (String) dataMap.get("personalityAnalysis");

            // 优先使用characterAnalysis，如果为空则使用personalityAnalysis
            fansContent.setCharacterAnalysis(characterAnalysis != null ?
                    characterAnalysis : personalityAnalysis);

            return fansContent;
        }
    }

    public String formatPrompt(String fansId, String cusNumber, int limit) {
        StringBuilder promptStringBuilder = new StringBuilder();
        List<ChatLog> chatlogList = chatLogMapper.selectChatLogByChat(fansId, limit);
        // 对 chatlogList 进行倒序排序
        for (int i = chatlogList.size() - 1; i >= 0; i--) {
            ChatLog chatLog = chatlogList.get(i);
            if (chatLog.getUserType().equals("1")) {
                if (StringUtils.isNotNull(chatLog.getTranslateText())) {
                    promptStringBuilder.append("[user]:").append(chatLog.getTranslateText()).append("\n");
                } else {
                    promptStringBuilder.append("[user]:").append(chatLog.getText()).append("\n");
                }
            }
        }

        return promptStringBuilder.toString();
    }

}
